//
// Created by 51399 on 2021/5/27.
//
#include "_socket.h"

void _test_() {
    te te1;
    te1.a = 0x12345678;
    printf("%u\n", &te1.b);
    printf("%u\n", &te1.a);
    printf("%d\n", te1.b);
}


void _socket_UDP(char *ip, char *port) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("错误连接");
        exit(1);
    }
    printf("socket fd : %d\n", sockfd);
    size_t i1 = strlen("asdasd\nasda");
    //填充信息
    struct sockaddr_in serveraddr;
    size_t addrlen = sizeof(serveraddr);
    int i = atoi(port);
    serveraddr.sin_port = htons(i);
    in_addr_t addr = inet_addr(ip);
    serveraddr.sin_addr.s_addr = addr;
    serveraddr.sin_family = AF_INET;
    //发送数据
    char buf[128];
    while (1) {
        fgets(buf, N, stdin);
        buf[strlen(buf) - 1] = '\0';
        if (sendto(sockfd, buf, N, 0, (struct sockaddr *) &serveraddr, addrlen) == -1) {
            perror("出错");
            exit(1);
        }
    }
    close(sockfd);
}


void _broadcast(char *ip, char *port) {
    int fd = create_socket(SOCK_DGRAM);
    int on = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
        perror("设置socket错误");
        exit(1);
    }
    struct sockaddr_in *pIn = (struct sockaddr_in *) create_sockaddrIn(port, ip);
    char buf[128] = "";
    while (1) {
        fgets(buf, 128, stdin);
        buf[strlen(buf) - 1] = '\0';
        if (sendto(fd, buf, 128, 0, (struct sockaddr *) pIn, sizeof(struct sockaddr_in)) < 0) {
            perror("fail to sendto");
            exit(1);
        }
    }

}


void _bind(char *port, char *ip) {

    int fd = create_socket(SOCK_DGRAM);
    struct sockaddr_in *pIn = (struct sockaddr_in *) create_sockaddrIn(port, ip);
    if (bind(fd, (struct sockaddr *) pIn, sizeof(struct sockaddr_in)) == -1) {
        perror("绑定失败");
        exit(1);
    }
    recvBuff(fd);
    close(fd);
}

void recvBuff(int fd) {
    char buf[128] = "";
    struct sockaddr_in addr;
    while (1) {
        size_t fromlen = sizeof(struct sockaddr_in);
        if (recvfrom(fd, buf, 128, 0, (struct sockaddr *) &addr, (socklen_t *) &fromlen) == -1) {
            perror("接受错误");
            exit(1);
        }
        printf("ip:%s, port:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        printf("打印内容:%s\n", buf);
    }
}

void *create_sockaddrIn(char *port, char *ip) {
    static struct sockaddr_in addr;
    addr.sin_port = htons(atoi(port));
    addr.sin_addr.s_addr = inet_addr(ip);
    addr.sin_family = AF_INET;
    return &addr;
}

int create_socket(int sockType) {
    int sockfd = socket(AF_INET, sockType, 0);
    if (sockfd == -1) {
        perror("错误连接");
        exit(1);
    }
    return sockfd;
}


void write_socket(int fd, struct sockaddr_in *serveraddr) {
    size_t tolen = sizeof(serveraddr);
    char buf[128] = "";
    if (sendto(fd, buf, 128, 0, ((struct sockaddr *) serveraddr), tolen) == -1) {
        perror("发送出错");
        exit(1);
    }
    printf("发送成功");
}

void _TCP_client(char *ip, char *port) {
    int fd = create_socket(SOCK_STREAM);
    struct sockaddr_in *pSockaddr = (struct sockaddr_in *) create_sockaddrIn(port, ip);
    if (connect(fd, (struct sockaddr *) pSockaddr, sizeof(struct sockaddr_in)) == -1) {

        perror("connect");
        exit(1);
    }
    // 发送数据
    char buf[128] = "";
    fgets(buf, 128, stdin);
    size_t i2 = strlen(buf) - 1;
    memset(buf, 'a', 128);
    buf[i2] = '\0';
    ssize_t i = send(fd, buf, strlen(buf) + 1, 0);
    printf("发送的字节数有:%d\n", i);
    if (i == -1) {
        perror("send");
        exit(1);
    }
    memset(buf, '\0', 128);
    // 接收数据
    ssize_t i1 = recv(fd, buf, 128, 0);
    if (i1 == -1) {
        perror("recv");
        exit(1);
    }
    printf("%s", buf);
}

void _TCP_server(char *ip, char *port) {
    int fd = create_socket(SOCK_STREAM);
    struct sockaddr_in *in = (struct sockaddr_in *) create_sockaddrIn(port, ip);
    if (bind(fd, (struct sockaddr *) in, sizeof(struct sockaddr_in)) == -1) {
        perror("bind error");
        exit(1);
    }
    if (listen(fd, 10) == -1) {
        perror("listen error");
        exit(1);
    }
    struct sockaddr_in remote_addr;
    socklen_t le;
    int remote_fd = accept(fd, (struct sockaddr *) &remote_addr, &le);
    if (remote_fd == -1) {
        perror("accept error");
        exit(1);
    }
    char buf[128];
    fgets(buf, 128, stdin);
    buf[strlen(buf) - 1] = '\0';
    ssize_t send_size = send(remote_fd, buf, strlen(buf) + 1, 0);
    if (send_size == -1) {
        perror("send error");
        exit(1);
    }
    printf("send_size %d", send_size);
    printf("%s\n", buf);
    memset(buf, 128, '\0');
    ssize_t recv_size = recv(remote_fd, buf, 128, 0);
    if (recv_size == -1) {
        perror("recv error");
        exit(1);
    }
    printf("revcsetsockopt size: %d", recv_size);
    printf("%s\n", buf);
}

